home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
081-090
/
amok89
/
amigaguide
/
hyperapp.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
16KB
|
563 lines
MODULE HyperApp;
(*---------------------------------------------------------------------------
** An example for using AmigaGuide.
**
** This is a translation of the HyperApp.c example supplied with the
** AmigaGuide v1.24 package.
**---------------------------------------------------------------------------
** Oberon: Amiga-Oberon v3.00, F. Siebert / A+L AG
**---------------------------------------------------------------------------
** 14-Apr-93 [lars] created
** 14-Apr-93 [lars] actual
**---------------------------------------------------------------------------
*)
IMPORT ag:AmigaGuide, e:Exec, gr:Graphics, i:Intuition, sys:SYSTEM, Utility,
(* $IF Debug *) Debug, (* $END *)
io, NoGuru, Requests, Strings;
(*-------------------------------------------------------------------------*)
TYPE
AppInfoPtr = UNTRACED POINTER TO AppInfo;
EMenuItemPtr = UNTRACED POINTER TO EMenuItem;
AppInfo = STRUCT
window : i.WindowPtr; (* Window pointer *)
done : BOOLEAN; (* Done yet? *)
amigaGuide : ag.AmigaGuideContext; (* Pointer to the AmigaGuide context *)
region : LONGINT; (* Region that the mouse if over *)
font : gr.TextFontPtr; (* Window font *)
END;
EMenuItem = STRUCT
(menuItem : i.MenuItem) (* Embedded menu structure *)
menuID : LONGINT; (* Menu ID *)
END;
(*-------------------------------------------------------------------------*)
(* Context ID's to be sent to AmigaGuide *)
TYPE
tContext = ARRAY 6 OF e.STRPTR;
CONST
context = tContext ( sys.ADR("MAIN"), sys.ADR("QUIT"), sys.ADR("GADGET"),
sys.ADR("OKAY"), sys.ADR("CANCEL"), NIL);
(*-------------------------------------------------------------------------*)
(* Simple little prompts to display within the application window *)
TYPE
tQuickHelp = ARRAY 6 OF e.STRPTR;
CONST
quickhelp = tQuickHelp ( sys.ADR("HyperApp Main Window"),
sys.ADR(""),
sys.ADR("Transmogrify Objects"),
sys.ADR("Positive Quit"),
sys.ADR("Negative Quit"),
NIL
);
(*-------------------------------------------------------------------------*)
(* Table of application functions *)
TYPE
FuncTable = PROCEDURE (ai : AppInfoPtr); (* Type of application functions *)
Funcs = ARRAY 6 OF FuncTable;
PROCEDURE ^ MainFunc (ai : AppInfoPtr);
PROCEDURE ^ QuitFunc (ai : AppInfoPtr);
PROCEDURE ^ GadgetFunc (ai : AppInfoPtr);
PROCEDURE ^ OkayFunc (ai : AppInfoPtr);
PROCEDURE ^ CancelFunc (ai : AppInfoPtr);
CONST
funcs = Funcs ( MainFunc, QuitFunc, GadgetFunc, OkayFunc, CancelFunc, NIL );
(*-------------------------------------------------------------------------*)
(* Various for the gui *)
CONST
Topaz8 = gr.TextAttr (sys.ADR("topaz.font"), 8, SHORTSET{}, SHORTSET{} );
IText3 = i.IntuiText ( 0, 0, gr.jam1, 2, 1, sys.ADR(Topaz8),
sys.ADR("Quit"), NIL );
MenuItem1 = EMenuItem ( NIL, 0, 0, 142, 9,
{i.itemText, i.commSeq, i.itemEnabled, i.highComp},
LONGSET{}, sys.ADR(IText3), NIL, 'Q', NIL, 0,
1
);
Menu1 = i.Menu ( NIL, 2, 0, 64, 0, {i.menuEnabled}, sys.ADR("Project"),
sys.ADR(MenuItem1), 0, 0, 0, 0 );
TYPE
BorderData = ARRAY 10 OF INTEGER;
CONST
BData1 = BorderData ( 0, 0, 94, 0, 94, 13, 0, 13, 0, 0 );
BData2 = BorderData ( 0, 0, 94, 0, 94, 13, 0, 13, 0, 0 );
Border1 = i.Border ( 0, 0, 1, 0, gr.jam1, 5, sys.ADR(BData1), NIL );
Border2 = i.Border ( 0, 0, 1, 0, gr.jam1, 5, sys.ADR(BData2), NIL );
IText1 = i.IntuiText ( 1, 0, gr.jam2, 26, 3, sys.ADR(Topaz8), sys.ADR("Cancel"), NIL );
IText2 = i.IntuiText ( 1, 0, gr.jam2, 40, 3, sys.ADR(Topaz8), sys.ADR("OK"), NIL );
Gadget3 = i.Gadget ( NIL, -120, -18, 95, 14, {i.gRelBottom, i.gRelRight},
{ i.relVerify }, i.boolGadget, sys.ADR(Border1), NIL,
sys.ADR(IText1), LONGSET{}, NIL, 4, NIL );
Gadget2 = i.Gadget ( sys.ADR(Gadget3), 12, -18, 95, 14, {i.gRelBottom},
{ i.relVerify }, i.boolGadget, sys.ADR(Border2), NIL,
sys.ADR(IText2), LONGSET{}, NIL, 3, NIL );
Gadget1 = i.Gadget ( sys.ADR(Gadget2), 12, 27, -40, -48,
i.gadgHComp + {i.gRelWidth, i.gRelHeight, i.selected},
{ i.toggleSelect, i.relVerify }, i.boolGadget,
NIL, NIL, NIL, LONGSET{}, NIL, 2, NIL );
WinTags = Utility.Tags2 ( i.waMenuHelp, e.true, Utility.done, 0 );
NewWindowStructure1 = i.ExtNewWindow (
0, 0, 640, 100, -1, -1,
LONGSET{ i.rawKey, i.closeWindow, i.menuPick, i.menuHelp, i.gadgetUp,
i.mouseMove },
LONGSET{ i.windowSizing, i.windowDrag, i.windowDepth, i.windowClose,
i.reportMouse, i.sizeBRight, i.activate, i.noCareRefresh,
i.nwExtended},
sys.ADR(Gadget1), NIL, sys.ADR("HyperApp (Press HELP over Gadget or Menu)"),
NIL, NIL, 320, 50, -1, -1, {i.wbenchScreen},
sys.ADR(WinTags)
);
VAR
newWin : i.ExtNewWindow;
b1, b2 : i.Border;
(*-------------------------------------------------------------------------*)
PROCEDURE PointInBox (x, y : INTEGER; box : i.IBox) : BOOLEAN;
(* Determine if a point is within a rectangle *)
BEGIN
RETURN (x >= box.left)
& (x <= (box.left + box.width))
& (y >= box.top)
& (y <= (box.top + box.height));
END PointInBox;
(*-------------------------------------------------------------------------*)
PROCEDURE gadgetBox (g : i.GadgetPtr; domain : i.IBoxPtr; VAR box : i.IBox);
(* Find the rectangle of a gadget *)
BEGIN
(* Set the 'normal' rectangle *)
box.left := g.leftEdge;
box.top := g.topEdge;
box.width := g.width;
box.height := g.height;
(* Check for relativity *)
IF i.gRelRight IN g.flags THEN INC (box.left, domain.width - 1); END;
IF i.gRelBottom IN g.flags THEN INC (box.top, domain.height - 1); END;
IF i.gRelWidth IN g.flags THEN INC (box.width, domain.width); END;
IF i.gRelHeight IN g.flags THEN INC (box.height, domain.height); END;
END gadgetBox;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleMenuEvent (msg : i.IntuiMessagePtr);
(* Process menu events *)
VAR
win : i.WindowPtr;
ai : AppInfoPtr;
selection : INTEGER;
item : EMenuItemPtr;
BEGIN
win := msg.idcmpWindow;
ai := win.userData;
selection := msg.code;
(* Turn off the menu button *)
INCL (win.flags, i.rmbTrap);
(* Process all menu events *)
WHILE selection # 0 DO
(* Get the MenuItem structure address *)
item := i.ItemAddress (win.menuStrip^, selection);
IF item # NIL THEN
funcs[item.menuID] (ai);
(* Get the next selection *)
selection := item.menuItem.nextSelect;
ELSE selection := 0;
END;
END;
(* Turn menu events back on. *)
EXCL (win.flags, i.rmbTrap);
END HandleMenuEvent;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleMenuHelp (msg : i.IntuiMessagePtr);
(* Process MenuHelp events *)
VAR
win : i.WindowPtr;
ai : AppInfoPtr;
item : EMenuItemPtr;
mnum, inum, snum : INTEGER;
BEGIN
win := msg.idcmpWindow;
ai := win.userData;
mnum := i.MenuNum (msg.code);
inum := i.ItemNum (msg.code);
snum := i.SubNum (msg.code);
io.WriteString ("m "); io.WriteInt (mnum, 1);
io.WriteString ("i "); io.WriteInt (inum, 1);
io.WriteString ("s "); io.WriteInt (snum, 1);
io.WriteLn;
(* Get the MenuItem structure address *)
item := i.ItemAddress (win.menuStrip^, msg.code);
IF item # NIL THEN
(* Set the AmigaGuide context *)
sys.SETREG(0, ag.SetAmigaGuideContext (ai.amigaGuide, item.menuID, NIL));
(* Display the node *)
sys.SETREG(0, ag.SendAmigaGuideContext (ai.amigaGuide, NIL));
ELSE
(* No selectable item where help was pressed *)
io.WriteString ("No item here\n");
END;
END HandleMenuHelp;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleMouseMove (msg : i.IntuiMessagePtr);
(* Process MouseMove events *)
VAR
win : i.WindowPtr;
ai : AppInfoPtr;
gad : i.GadgetPtr;
box : i.IBox;
region : LONGINT;
tx, ty, bx, by : INTEGER;
BEGIN
win := msg.idcmpWindow;
ai := win.userData;
gad := win.firstGadget;
IF (msg.mouseX < 0) OR (msg.mouseX > win.width) OR
(msg.mouseY < 0) OR (msg.mouseY > win.height)
THEN
region := -1;
ELSE
region := 0;
(* Step through the gadgets to see which one the pointer was over *)
WHILE (gad # NIL) & (region = 0) DO
(* Calculate the gadget rectangle *)
gadgetBox (gad, sys.VAL(i.IBoxPtr, sys.ADR(win.leftEdge)), box);
(* Is the pointer within this gadget? *)
IF PointInBox (msg.mouseX, msg.mouseY, box) THEN
(* Is it not a system gadget? *)
IF gad.gadgetType >= 0 THEN
(* Set the region *)
region := gad.gadgetID;
END;
END;
(* Get the next gadget *)
gad := gad.nextGadget;
END;
END;
IF region # ai.region THEN
tx := win.borderLeft + 8;
ty := win.borderTop + 2;
bx := win.width - (win.borderRight + 8);
by := ty + win.rPort.txHeight;
gr.SetDrMd (win.rPort, gr.jam1);
(* Clear the quick help region *)
gr.SetAPen (win.rPort, 0);
gr.RectFill (win.rPort, tx, ty, bx, by);
(* Remember the region *)
ai.region := region;
(* Display the quick help if within the window *)
IF region >= 0 THEN
gr.SetAPen (win.rPort, 1);
gr.Move (win.rPort, tx, ty + win.rPort.txBaseline);
gr.Text (win.rPort, quickhelp[region]^, Strings.Length (quickhelp[region]^));
END;
END;
END HandleMouseMove;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleGadgetHelp (msg : i.IntuiMessagePtr);
(* Process GadgetHelp events *)
VAR
win : i.WindowPtr;
ai : AppInfoPtr;
gad : i.GadgetPtr;
box : i.IBox;
region : LONGINT;
sysg : LONGINT;
BEGIN
win := msg.idcmpWindow;
ai := win.userData;
gad := win.firstGadget;
region := 0;
(* Step through the gadgets to see which one the pointer was over *)
WHILE (gad # NIL) & (region = 0) DO
(* Calculate the gadget rectangle *)
gadgetBox (gad, sys.VAL(i.IBoxPtr, sys.ADR(win.leftEdge)), box);
(* Is the pointer within this gadget? *)
IF PointInBox (msg.mouseX, msg.mouseY, box) THEN
(* Is it a system gadget? *)
IF gad.gadgetType < 0 THEN
sysg := sys.VAL (INTEGER, sys.LSH(sys.VAL(SET, gad.gadgetType) * {4..7}, -4));
(* Set the region *)
region := sys.VAL (LONGINT, LONGSET{ag.sysGads}) + sysg;
ELSE
(* Set the region *)
region := gad.gadgetID;
END;
END;
(* Get the next gadget *)
gad := gad.nextGadget;
END;
(* Set the AmigaGuide context. *)
sys.SETREG(0, ag.SetAmigaGuideContext (ai.amigaGuide, region, NIL));
(* Display the current node *)
sys.SETREG(0, ag.SendAmigaGuideContext (ai.amigaGuide, NIL));
END HandleGadgetHelp;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleGadgetEvent (msg : i.IntuiMessagePtr);
(* Process Gadget events *)
VAR
win : i.WindowPtr;
ai : AppInfoPtr;
gad : i.GadgetPtr;
BEGIN
win := msg.idcmpWindow;
ai := win.userData;
gad := msg.iAddress;
IF gad # NIL THEN funcs[gad.gadgetID] (ai); END;
END HandleGadgetEvent;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleIDCMP (VAR ai : AppInfo);
(* Process Intuition messages *)
VAR
win : i.WindowPtr;
imsg : i.IntuiMessagePtr;
BEGIN
win := ai.window;
LOOP
imsg := e.GetMsg (win.userPort);
IF imsg = NIL THEN EXIT; END;
IF i.mouseMove IN imsg.class THEN HandleMouseMove (imsg);
ELSIF i.closeWindow IN imsg.class THEN ai.done := TRUE;
ELSIF i.menuPick IN imsg.class THEN HandleMenuEvent (imsg);
ELSIF i.menuHelp IN imsg.class THEN HandleMenuHelp (imsg);
ELSIF i.gadgetUp IN imsg.class THEN HandleGadgetEvent (imsg);
ELSIF (i.rawKey IN imsg.class) & (imsg.code = 95) THEN HandleGadgetHelp (imsg);
END;
(* Reply to the message *)
e.ReplyMsg (imsg);
END;
END HandleIDCMP;
(*-------------------------------------------------------------------------*)
PROCEDURE DisplayError (err : LONGINT);
BEGIN
io.WriteString (ag.GetAmigaGuideString (err)^);
io.WriteLn;
END DisplayError;
(*-------------------------------------------------------------------------*)
PROCEDURE HandleAmigaGuide (VAR ai : AppInfo);
(* Process AmigaGuide messages *)
VAR
agm : ag.AmigaGuideMsgPtr;
BEGIN
LOOP
agm := ag.GetAmigaGuideMsg (ai.amigaGuide);
IF agm = NIL THEN EXIT; END;
(* check message types *)
CASE agm.type OF
| ag.activeToolID: (* AmigaGuide is ready for us *)
| ag.toolCmdReplyID: (* This is a reply to our cmd *)
IF agm.priRet # 0 THEN DisplayError (agm.secRet); END;
| ag.toolStatusID: (* This is a status message *)
IF agm.priRet # 0 THEN DisplayError (agm.secRet); END;
| ag.shutdownMsgID: (* Shutdown message *)
IF agm.priRet # 0 THEN DisplayError (agm.secRet); END;
ELSE (* ignore it *)
END;
(* Reply to the message *)
ag.ReplyAmigaGuideMsg (agm);
END;
END HandleAmigaGuide;
(*-------------------------------------------------------------------------*)
(* The called back functions *)
PROCEDURE * MainFunc (ai : AppInfoPtr);
BEGIN io.WriteString ("I don't do anything...\n"); END MainFunc;
PROCEDURE * QuitFunc (ai : AppInfoPtr);
BEGIN
(* All done, guys *)
ai.done := TRUE;
END QuitFunc;
PROCEDURE * GadgetFunc (ai : AppInfoPtr);
BEGIN io.WriteString ("Pressed the big gadget\n"); END GadgetFunc;
PROCEDURE * OkayFunc (ai : AppInfoPtr);
BEGIN
(* All done, guys *)
ai.done := TRUE;
END OkayFunc;
PROCEDURE * CancelFunc (ai : AppInfoPtr);
BEGIN
(* All done, guys *)
ai.done := TRUE;
END CancelFunc;
(*-------------------------------------------------------------------------*)
PROCEDURE Main ();
VAR
nag : ag.NewAmigaGuide;
ai : AppInfo;
sigr, sigi, sigb : LONGSET;
BEGIN
(* Open the window font *)
ai.font := gr.OpenFont (Topaz8);
IF ai.font = NIL THEN io.WriteString ("Can't open font 'topaz 8'.\n");
ELSE
(* Open the window *)
ai.window := i.OpenWindow (NewWindowStructure1);
IF ai.window = NIL THEN io.WriteString ("Can't open window.\n");
ELSE
sigr := LONGSET{};
sigi := LONGSET{};
sigb := LONGSET{};
(* Set the window font *)
gr.SetFont (ai.window.rPort, ai.font);
(* Set the menu *)
sys.SETREG(0, i.SetMenuStrip (ai.window, Menu1));
(* Remember the AppInfo *)
ai.window.userData := sys.ADR(ai);
(* Show that we're not done running the application yet *)
ai.done := FALSE;
(* Set the application base name *)
nag.baseName := sys.ADR("HyperApp");
(* Set the document name *)
nag.name := sys.ADR("hyperapp.guide");
(* establish the base name to use for hypertext ARexx port *)
nag.clientPort := sys.ADR("AGAPP_HELP");
(* Set up the context table *)
nag.context := sys.ADR(context);
(* Open the help system *)
ai.amigaGuide := ag.OpenAmigaGuideAsync (nag, NIL);
(* Get our signal bits *)
sigb := ag.AmigaGuideSignal (ai.amigaGuide);
sigi := LONGSET{ai.window.userPort.sigBit};
(* Clear the AmigaGuide context *)
sys.SETREG(0, ag.SetAmigaGuideContext (ai.amigaGuide, 0, NIL));
(* Continue until done *)
WHILE ~ai.done DO
(* Wait for something to happen *)
sigr := e.Wait (sigb + sigi);
(* Process Intuition messages *)
IF sigr * sigi # LONGSET{} THEN HandleIDCMP (ai); END;
(* Process AmigaGuide messages *)
IF sigr * sigb # LONGSET{} THEN HandleAmigaGuide (ai); END;
END;
(* Shutdown the help system *)
ag.CloseAmigaGuide (ai.amigaGuide);
(* Do we have a menu? *)
IF ai.window.menuStrip # NIL THEN
(* Clear it *)
i.ClearMenuStrip (ai.window);
END;
(* Close the application window *)
i.CloseWindow (ai.window);
END;
(* Close the font *)
gr.CloseFont (ai.font);
END;
END Main;
(*-------------------------------------------------------------------------*)
BEGIN
Requests.Assert (ag.base # NIL, "Can't open amigaguide.library");
newWin := NewWindowStructure1;
b1 := Border1;
b2 := Border2;
Main;
END HyperApp.
(***************************************************************************)